package com.surfilter.massdata.es.core.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;

import com.surfilter.massdata.es.core.entity.EsEntity;
import com.surfilter.massdata.es.core.entity.EsEntityUtil;


/**
 * 
 * ES 工具类
 * 
 * @author liuchen
 *
 */
public class EsUtil {
	public static String _prefix = "p";
	
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	/**
	 * like 条件
	 * @param fieldName 列名
	 * @param queryString  条件字符串
	 * @return
	 */
/*	public static FilterBuilder conditionLike(String fieldName, String queryString){
		return FilterBuilders.queryFilter(QueryBuilders.wildcardQuery(fieldName, EsUtil._prefix + "*" + queryString + "*"));
	}*/
	public static QueryBuilder conditionLike(String fieldName, String queryString){
		return QueryBuilders.wildcardQuery(fieldName,  "*" + queryString + "*");
	}
	
	/**
	 * 与或 条件
	 * @param fieldName 列名
	 * @param andQueryString  与查询字符串
	 * @param orQueryString  或查询字符串
	 * @return
	 */
/*	public static FilterBuilder conditionAndOr(String fieldName, String andQueryString,String orQueryString){
		
		WildcardQueryBuilder  wildcardQueryBuilder = QueryBuilders.wildcardQuery(fieldName, EsUtil._prefix + "*" + andQueryString + "*");
		return FilterBuilders.queryFilter(QueryBuilders.wildcardQuery(fieldName, EsUtil._prefix + "*" + andQueryString + "*"));
	}*/
	
	/**
	 * like 条件
	 * @param fieldName 列名
	 * @param queryString  条件字符串
	 * @return
	 */
	public static QueryBuilder conditionLikeIp(String fieldName, String queryString){
		return QueryBuilders.wildcardQuery(fieldName, "*" + queryString + "*");
	}
	
	/**
	 * like 条件
	 * @param fieldName 列名
	 * @param queryString  条件字符串
	 * @return
	 */
	public static QueryBuilder conditionQueryLike(String fieldName, String queryString){
		return QueryBuilders.wildcardQuery(fieldName, "*" + queryString + "*");
	}
	
	/**
	 * 
	 * equal 条件（字符串类型）
	 * 
	 * @param fieldName 列名
	 * @param queryString 条件字符串
	 * @return
	 */
	public static QueryBuilder conditionEqual(String fieldName, String queryString){
		return QueryBuilders.termQuery(fieldName, queryString);
	}
	
	/**
	 * 
	 * equal 条件（字符串类型）
	 * 
	 * @param fieldName 列名
	 * @param queryString 条件字符串
	 * @return
	 */
	public static QueryBuilder conditionQueryEqual(String fieldName, String queryString){
		return QueryBuilders.queryStringQuery(queryString).field(fieldName);
	}
	
	/**
	 * equal 条件（long类型）
	 * 
	 * @param fieldName 列名
	 * @param value 条件值
	 * @return
	 */
/*	public static FilterBuilder conditionEqual(String fieldName, long value){
		return FilterBuilders.termFilter(fieldName, value);
	}*/
	public static QueryBuilder conditionEqual(String fieldName, long value){
		return QueryBuilders.termQuery(fieldName, value);
	}
	/**
	 * 
	 * equal 条件（long类型）
	 * 
	 * @param fieldName 列名
	 * @param queryString 条件字符串
	 * @return
	 */
	public static QueryBuilder conditionQueryEqual(String fieldName, long value){
		return QueryBuilders.termQuery(fieldName, value);
	}
	
	/**
	 * equal 条件（int类型）
	 * 
	 * @param fieldName 列名
	 * @param value 条件值
	 * @return
	 */
/*	public static FilterBuilder conditionEqual(String fieldName, int value){
		return FilterBuilders.termFilter(fieldName, value);
	}*/
	
	/**
	 * 
	 * equal 条件（int类型）
	 * 
	 * @param fieldName 列名
	 * @param queryString 条件字符串
	 * @return
	 */
	public static QueryBuilder conditionQueryEqual(String fieldName, int value){
		return QueryBuilders.termQuery(fieldName, value);
	}
	
	/**
	 * equal 条件（short类型）
	 * 
	 * @param fieldName 列名
	 * @param value 条件值
	 * @return
	 */
/*	public static FilterBuilder conditionEqual(String fieldName, short value){
		return FilterBuilders.termFilter(fieldName, value);
	}*/
	
	/**
	 * 
	 * equal 条件（short类型）
	 * 
	 * @param fieldName 列名
	 * @param queryString 条件字符串
	 * @return
	 */
	public static QueryBuilder conditionQueryEqual(String fieldName, short value){
		return QueryBuilders.termQuery(fieldName, value);
	}
	
	/**
	 * equal 条件（double类型）
	 * 
	 * @param fieldName 列名
	 * @param value 条件值
	 * @return
	 */
/*	public static FilterBuilder conditionEqual(String fieldName, double value){
		return FilterBuilders.termFilter(fieldName, value);
	}*/
	
	/**
	 * 
	 * equal 条件（double类型）
	 * 
	 * @param fieldName 列名
	 * @param queryString 条件字符串
	 * @return
	 */
	public static QueryBuilder conditionQueryEqual(String fieldName, double value){
		return QueryBuilders.termQuery(fieldName, value);
	}
	
	public static QueryBuilder conditionRangeNumber(String fieldName, Long min, Long max ) {
		RangeQueryBuilder rangeFB = QueryBuilders.rangeQuery(fieldName);
		
		boolean flag = true;
		if(min!=null){
			rangeFB.gte(min);
			flag = false;
		}
		if(max!=null){
			rangeFB.lte(max);
			flag = false;
		}
		if(flag){
			rangeFB = null;
		}
		return rangeFB;
		
	}
	
	public static QueryBuilder conditionRangeString(String fieldName,String minString, String maxString) {
		RangeQueryBuilder rangeFB = QueryBuilders.rangeQuery(fieldName);
		
		boolean flag = true;
		if(StringUtil.isNotNull(minString)){
			rangeFB.gte(minString);
			flag = false;
		}
		if(StringUtil.isNotNull(maxString)){
			rangeFB.lte(maxString);
			flag = false;
		}
		if(flag){
			rangeFB = null;
		}
		return rangeFB;
	}
	
	public static  QueryBuilder conditionRangeDate(String fieldName, Date beginDate, Date endDate ) throws ParseException{
		RangeQueryBuilder rangeFB = QueryBuilders.rangeQuery(fieldName);
		
		boolean flag = true;
		if(beginDate!=null){
			/*
			 *  由于ES date类型采用UTC，必须添加8小时
			 *  @link{http://www.elasticsearch.org/guide/reference/api/search/facets/date-histogram-facet/ 
			 *        里面的Time Zone} 
			 */
			rangeFB.gte(DateUtils.getUTCTime(beginDate));
			flag = false;
		}
		if(endDate!=null){
			/*
			 *  由于ES date类型采用UTC，必须添加8小时
			 *  @link{http://www.elasticsearch.org/guide/reference/api/search/facets/date-histogram-facet/ 
			 *        里面的Time Zone} 
			 */
			rangeFB.lte( DateUtils.getUTCTime(endDate) );
			flag = false;
		}
		if(flag){
			rangeFB = null;
		}
		return rangeFB;
		
	}
	
	public static  QueryBuilder conditionRangeDateString(String fieldName, String beginDate, String endDate ) throws ParseException{
		RangeQueryBuilder rangeFB = QueryBuilders.rangeQuery(fieldName);
		
		boolean flag = true;
		if(StringUtil.isNotNull(beginDate)){
			Date createDateBegin = sdf.parse(beginDate);
			/*
			 *  由于ES date类型采用UTC，必须添加8小时
			 *  @link{http://www.elasticsearch.org/guide/reference/api/search/facets/date-histogram-facet/ 
			 *        里面的Time Zone} 
			 */
//			rangeFB.gte(DateUtil.getUTCTime(createDateBegin));
			rangeFB.gte(beginDate);
			flag = false;
		}
		if(StringUtil.isNotNull(endDate)){
			Date createDateEnd = sdf.parse(endDate);
			/*
			 *  由于ES date类型采用UTC，必须添加8小时
			 *  @link{http://www.elasticsearch.org/guide/reference/api/search/facets/date-histogram-facet/ 
			 *        里面的Time Zone} 
			 */
//			rangeFB.lte( DateUtil.getUTCTime(createDateEnd) );
			rangeFB.lte( endDate);//资源协作访问日志时间查询报时间格式的时候修改,上一行是之前的写法
			flag = false;
		}
		if(flag){
			rangeFB = null;
		}
		return rangeFB;
		
	}
	
	
	public static QueryBuilder conditionEqual(String fieldName, String[] arr){
		return QueryBuilders.termsQuery(fieldName, arr);
	}
	
	
	/**
	 * 
	 *  distinct 查询
	 * 
	 * @param esClient  es客户端
	 * @param distinctFieldName 
	 * @param idFieldName
	 * @param pageNo
	 * @param pageSize
	 * @param maxSize
	 * @return
	 */
/*	public static Map<Integer,SearchResponse> distinctQuery(EsClient esClient ,String indexName,String typeName,QueryBuilder queryBuilder,
			String distinctFieldName, String idFieldName,int pageNo, int pageSize , int maxSize){
		SearchRequestBuilder srb = esClient.getEsSearch().setIndices(indexName).setTypes(typeName);
		// first Query
		SearchResponse searchResponse = srb.setQuery(queryBuilder)
			.addFacet(
					FacetBuilders.termsStatsFacet("facetDistinct").keyField(distinctFieldName).valueField(idFieldName)
						.size(maxSize)
					)
			.execute().actionGet();
		EsUtil.print(srb);
		
		TermsStatsFacet facet = searchResponse.getFacets().facet("facetDistinct");
		List<? extends TermsStatsFacet.Entry> lstEntry = facet.getEntries();
		
		int facetsSize = facet.getEntries().size();
		if(facetsSize < 1){
			return null;
		}
		if (facetsSize < pageSize) {
			pageSize = facetsSize;
		}
		long[] arrId = new long[pageSize];
		int i = 0;
		for (int j = (pageNo-1)*pageSize , size = pageNo * pageSize; j < size && j < facetsSize; j++) {
			arrId[i++] = (long) lstEntry.get(j).getMin();
		}
		
		srb = esClient.getEsSearch();
		
		searchResponse = srb
				.setPostFilter(FilterBuilders.inFilter(idFieldName, arrId))
			.execute().actionGet();
		
		EsUtil.print(srb);
		
		Map <Integer,SearchResponse> map = new HashMap<Integer, SearchResponse>(1);
		map.put(facetsSize, searchResponse);
		return map;
	}*/
	
	public static void print(SearchRequestBuilder srb){
    	// 输出_search 请求的json串
 		System.out.println("request:"+srb.toString());
    }
    
	public static void print(SearchRequestBuilder srb,SearchResponse searchResponse){
    	print(srb);
		// 输出结果
		System.out.println("response:"+searchResponse.toString());
    }
	
	/**
	 * 
	 * 获取查询结果集总数
	 * 
	 * @param searchResponse ES查找结果对象
	 * @return 结果集总数
	 */
	public static long getCount(SearchResponse searchResponse){
		return searchResponse.getHits().getTotalHits();
	}
	
	/**
	 * 
	 * 转换ES查找结果为实体集合
	 * 
	 * @param searchResponse ES查找结果对象
	 * @param esEntity 实体
	 * @return t类型的实体集合
	 */
	public static <T extends EsEntity> List<? extends Object> getEntity(SearchResponse searchResponse ,T t){
		SearchHit[] arrHits = searchResponse.getHits().getHits();
		
		List<Object> lstEsEntity = new ArrayList<Object>(arrHits.length);
		for (int i = 0 ,size = arrHits.length; i < size; i++) {
			Map<String, Object> propertiesMap = (Map<String, Object>) arrHits[i].getSource();
			Object esObject =  t.recoveEntity(propertiesMap);
			lstEsEntity.add(esObject);
		}
		return lstEsEntity;
	}
	
	/**
	 * 
	 * 转换ES查找结果为实体集合
	 * 
	 * @param searchResponse ES查找结果对象
	 * @param esEntity 实体
	 * @return t类型的实体集合
	 */
	public static Map<String,List<String>> getResultMap(SearchResponse searchResponse,String keyField,String valueField){
		SearchHit[] arrHits = searchResponse.getHits().getHits();
		
		Map<String,List<String>> resultMap = new HashMap<String, List<String>>();
		List<String> resultList = new ArrayList<String>();
		String key = "";
		for (int i = 0 ,size = arrHits.length; i < size; i++) {
			Map<String, SearchHitField> propertiesMap = (Map<String, SearchHitField>) arrHits[i].getFields();
			Iterator<String> it =  propertiesMap.keySet().iterator();
			while (it.hasNext()) {
				String mapKey = it.next();
				if(keyField.equals(mapKey)){
					SearchHitField hit = propertiesMap.get(mapKey);
					
					List<Object> values =  hit.getValues();
					if(values !=null && values.size() >0){
						key = String.valueOf(values.get(0)).substring(1);
					}
				}
				if(valueField.equals(mapKey)){
					
					SearchHitField hit = propertiesMap.get(mapKey);
					
					List<Object> values =  hit.getValues();
					if(values !=null && values.size() >0){
						for (Object value : values) {
							if(!resultList.contains(value)){
								resultList.add(String.valueOf(value).substring(1));
							}
						}
					}
				}
			}
		}
		resultMap.put(key, resultList);
		return resultMap;
	}
	
	public static <T extends EsEntity> List<? extends Object> getEntityAndIndex(SearchResponse searchResponse ,T t){
		SearchHit[] arrHits = searchResponse.getHits().getHits();
		
		List<Object> lstEsEntity = new ArrayList<Object>(arrHits.length);
		for (int i = 0 ,size = arrHits.length; i < size; i++) {
			Map<String, Object> propertiesMap = (Map<String, Object>) arrHits[i].getSource();
			Object esObject =  t.recoveEntityAndIndex(propertiesMap,arrHits[i]);
			lstEsEntity.add(esObject);
		}
		return lstEsEntity;
	}
	
	
	/**
	 * 
	 * 转换ES查找结果为实体集合
	 * 
	 * @param searchResponse ES查找结果对象
	 * @param esEntity 实体
	 * @return t类型的实体集合
	 */
	public static <T extends EsEntityUtil> List<? extends Object> getEntity(SearchResponse searchResponse ,T t){
		SearchHit[] arrHits = searchResponse.getHits().getHits();
		
		List<Object> lstEsEntity = new ArrayList<Object>(arrHits.length);
		for (int i = 0 ,size = arrHits.length; i < size; i++) {
			Map<String, Object> propertiesMap = (Map<String, Object>) arrHits[i].getSource();
			propertiesMap.put("index", arrHits[i].getIndex());
			Object esObject =  t.recoveEntity(propertiesMap,null);
			lstEsEntity.add(esObject);
		}
		return lstEsEntity;
	}
	
	
	public static Long[] transformLongArr(String source ,String splitStr , int arrSize){
		if (StringUtil.isNull(splitStr) && arrSize > 0){
			return null;
		}
		Long[] arrReturn = new Long[arrSize];
		if (source != null ) {
			String[] arrStr = source.split(splitStr);
			for (int i = 0 ,strSize = arrStr.length; i < arrSize ; i++) {
				if (i < strSize) {
					try {
						arrReturn[i] = Long.valueOf( arrStr[i] );
					} catch (NumberFormatException e) {
						arrReturn[i] = 0l;
					}
					
				} else {
					arrReturn[i] = 0l;
				}
			}
		} else {
			for (int i = 0 ; i < arrSize ; i++) {
				arrReturn[i] = 0l;
			}
		}
		return arrReturn;
	}
	
	
	public static String[] transformStringArr(String source ,String splitStr , int arrSize){
		if (StringUtil.isNull(splitStr) && arrSize > 0){
			return null;
		}
		String[] arrReturn = new String[arrSize];
		if (source != null ) {
			String[] arrStr = source.split(splitStr);
			for (int i = 0 ,strSize = arrStr.length; i < arrSize ; i++) {
				if (i < strSize) {
					arrReturn[i] = arrStr[i];
				} else {
					arrReturn[i] = "";
				}
			}
		} else {
			for (int i = 0 ; i < arrSize ; i++) {
				arrReturn[i] = "";
			}
		}
		return arrReturn;
	}
 
//	public static String removePrefix(String str) {
//		String returnStr = null;
//		if (StringUtil.isNotNull(str)) {
//			returnStr = str.substring(1);
//		}
//		return returnStr;
//	}
	
	public static void main(String[] args) {
		String s = "s";
		Object o = "s";
		List<String> l = new ArrayList<String>();
		l.add(s);
		System.out.println(l.contains(o));
	}


	
}
